import React from 'react';

interface SwipeInput {
  onSwipedUp: () => void;
  onSwipedDown?: () => void;
}

interface SwipeOutput {
  onTouchStart: (e: React.TouchEvent) => void;
  onTouchMove: (e: React.TouchEvent) => void;
  onTouchEnd: () => void;
}

export const useSwipe = (input: SwipeInput): SwipeOutput => {
  const [touchStart, setTouchStart] = React.useState(0);
  const [touchEnd, setTouchEnd] = React.useState(0);

  const minSwipeDistance = 20;

  const onTouchStart = (e: React.TouchEvent) => {
    setTouchEnd(0); // otherwise the swipe is fired even with usual touch events
    setTouchStart(e.targetTouches[0].clientY);
  };

  const onTouchMove = (e: React.TouchEvent) => setTouchEnd(e.targetTouches[0].clientY);

  const onTouchEnd = () => {
    if (!touchStart || !touchEnd) return;
    const distance = touchStart - touchEnd;
    const isUp = distance > minSwipeDistance;
    const isDown = distance < -minSwipeDistance;
    if (isUp) {
      input.onSwipedUp();
    }
    if (isDown && input.onSwipedDown) {
      input.onSwipedDown();
    }
  };
  return {
    onTouchStart,
    onTouchMove,
    onTouchEnd,
  };
};
